package com.sky.aop;

import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import com.sky.exception.AopAutoFillException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * @Description AutoFillAspect
 * @Author zhengyuan&junjun
 * @Date 2024-10-01
 */
@Aspect  //指定当前类为Aop类
@Component  //加入IO容器
public class AutoFillAspect {


    //创建切入点
    @Pointcut(value = "@annotation(com.sky.aop.AutoFill)")  //切入点表达式
    public void autoFillPoinCut() {


    }

    /**创建通知功能的方法**/
    /***
     * joinPoint内部封装了切入点的信息
     */

    @Before("autoFillPoinCut()")// @Before用于定义前置通知。
    public void autoFill(JoinPoint joinPoint) throws AopAutoFillException {//JoinPoint连接点是程序执行过程中能够插入切面的点，例如方法的执行。

        System.out.println("----------aop:用户正在进行修改或添加操作-----------");


        //获取实体
        Object entity = joinPoint.getArgs()[0];  //获取数组的第一个元素

       //获取切入点的方法和注解
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

        AutoFill autoFill = methodSignature.getMethod().getAnnotation(AutoFill.class);
        //获取方法值
        OperationType value = autoFill.value();
        //判断切入的方法是新增还是修改
        try {
            if (value == OperationType.INSERT) {
                //新增
                //给实体属性赋值
                //反射机制获取方法
                Class<?> aClass = entity.getClass();//获取方法的字节码对象
                Method setCreateUser = aClass.getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);  //获取实体对象中的属性
                Method setUpdateUser = aClass.getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                Method setCreateTime = aClass.getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = aClass.getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                //调用方法给属性赋值
                setCreateUser.invoke(entity, BaseContext.getCurrentId());
                setUpdateUser.invoke(entity, BaseContext.getCurrentId());
                setCreateTime.invoke(entity, LocalDateTime.now());
                setUpdateTime.invoke(entity, LocalDateTime.now());

            } else if (value == OperationType.UPDATE) {
                //修改
                Class<?> aClass = entity.getClass();//获取方法的字节码对象
                Method setUpdateUser = aClass.getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                Method setUpdateTime = aClass.getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                //调用方法给属性赋值

                setUpdateUser.invoke(entity, BaseContext.getCurrentId());
                setUpdateTime.invoke(entity, LocalDateTime.now());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new AopAutoFillException("aop自动填充异常");


        }




    }
}


